import { mapYearToLandscapeZ } from '@src/utils/utils'

export default function mixinObjects (Incident) {
  var objectXorgen = new xor4096('hello.');

  Incident.prototype.createObjects = function(objectArray) {
    const self = this;

    var blobs = new THREE.Object3D();
    blobs.frustumCulled = false;

    var sticks = new THREE.Object3D();
    sticks.frustumCulled = false;

    /*if (!this.objects) {
      this.objects = this.objects = {
        blobs: blobs,
        sticks: sticks
      };
    }*/

    const { category, geoLane, colors } = this.geographies
    // var category = this.geographies.category;
    // var geoLane = this.geographies.geoLane;
    // var colors = this.geographies.colors;

    var blobLayoutGrid = {};
    var fitBlob = function(v) {
      var vx = Math.floor(v.x/2);
      var vy = Math.floor(v.y/2);
      var vz = Math.floor(v.z/2);
      var k = [vx, vy, vz].join(":");
      if (!blobLayoutGrid[k]) {
        for (var x = -1; x <= 1; x++) {
          for (var y = -1; y <= 1; y++) {
            for (var z = -1; z <= 1; z++) {
              k = [vx+x, vy+y, vz+z].join(":");
              blobLayoutGrid[k] = true;
            }
          }
        }

        return true;
      }
      return false;
    };
    var blobShift = function(v) {
      var i = 0;
      while (!fitBlob(v)) {
        if (i === 0) { v.x += 2; }
        else if (i === 1) { v.x += -4; }
        else if (i === 2) { v.x += 2; v.y += 2; }
        else if (i === 3) { v.x += 0; v.y += -4; }
        else if (i === 4) { v.x += 2; v.y += 0; }
        else if (i === 5) { v.x += -4; v.y += 0; }
        else if (i === 6) { v.x += 0; v.y += 4; }
        else if (i === 7) { v.x += 4; v.y += 0; }
        else if (i === 8) { v.z += 4; break; }
        i++;
      }
    };

    var clamp = function(x) {
      return x > 1 ? 1 : (x < 0 ? 0 : x);
    };

    var shaderMaterial = this.canvasShaderMaterial;

    // cultureName： 对应轴 的名字
    objectArray = objectArray.filter(function(obj) {
      return geoLane[obj.cultureName] !== undefined;
    });

    for (var i=0; i<objectArray.length; i++) {
      var obj = objectArray[i];
      // 对应轨道
      var lane = geoLane[obj.cultureName];

      // 对应轨道的颜色
      var color = new THREE.Color( colors[lane] || 0x0 );
      obj.backgroundColor = color.getStyle();

      color.r = clamp(color.r * (1+(Math.random() - 0.5) * 0.2));
      color.g = clamp(color.g * (1+(Math.random() - 0.5) * 0.2));
      color.b = clamp(color.b * (1+(Math.random() - 0.5) * 0.2));

      // 着色器拷贝
      var mat = shaderMaterial.clone();
      mat.color = color;
      mat.colorChangeSpeed = 0.25;
      mat.colorChangeDelay = Math.ceil(Math.random()*30);
      mat.uniforms = {
        map: {type: 't', value: this.blobTextures[i % this.blobTextures.length]},
        color: {type: 'v3', value: new THREE.Vector3(color.r, color.g, color.b)}
      };
      var blob = new THREE.Mesh(this.itemGeometry, mat);

      blob.rotation.z = Math.random() * Math.PI * 2;

      blob.laneIndex = lane;

      blob.objectData = obj;
      this.blobIndex[obj.bullet] = blob;

      blob.connections = [];
      blob.frustumCulled = false;
      blob.sticksContainer = new THREE.Object3D();
      blob.sticksContainer.visible = false;
      blob.sticksContainer.frustumCulled = false;
      blob.sticksContainer.tick = this.scene.tick;
      blob.frustumCulled = false;
      blob.position.set(
        6*(6/5) * (lane-(category.length-1)/2)+4*(objectXorgen()-0.5),
        -10+objectXorgen()*5,
        mapYearToLandscapeZ(obj.dateCreated, true)
      );

      blobShift(blob.position);
      blob.originalPosition = blob.position.clone();

      blob.scale.multiplyScalar(1.5);
      blob.relativePos = new THREE.Vector3();
      blob.targetPos = new THREE.Vector3();
      blob.velocity = new THREE.Vector3();
      blob.floatVec = new THREE.Vector3();
      blob.posDelta = new THREE.Vector3();
      blob.tick = function () {
        self.blobTick.call(this, self)
      };

      blob.sticks = [];

      blob.addConnection = function (connection) {
        self.addBlobConnection.call(this, connection, self)
      };

      blob.hoverConnectionTarget = blob.clone();
      blob.hoverConnectionTarget.scale.set(0.01, 0.01, 0.01);
      blob.addConnection(blob.hoverConnectionTarget);

      blobs.add(blob);
    }

    return {blobs: blobs, sticks: sticks};
  }
}
